package com.navinfo.tripanalysis.common.arithmetic;

import com.navinfo.tripanalysis.common.arithmetic.annotation.Arithmetic;
import com.navinfo.tripanalysis.common.arithmetic.common.CommonData;
import com.navinfo.tripanalysis.common.arithmetic.common.OuterStatisticData;
import com.navinfo.tripanalysis.common.arithmetic.custom.VarCarStop;
import com.navinfo.tripanalysis.common.arithmetic.enums.EventType;
import com.navinfo.tripanalysis.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.tripanalysis.common.config.ConfigMap;

import java.util.Optional;

/**
 * 东风新版，紧急停车算法.<br>
 *      1.车辆处于 ON 档状态；<br>
 *      2.油门开度在5秒内从>50%到油门开到=0；<br>
 *      3.减速度 < -5m/𝑠2；<br>
 *      4.识别为一次紧急事件；<br>
 * 依赖{@link Mileage}里程油耗算法<br/>
 * 输出：统计、事件<br/>
 */
@Arithmetic(name = "东风新版，紧急停车算法")
public class EmergencyStop_DFN extends AbstractArithmetic<VarCarStop> {
    /**
     * 事件类型
     */
    private final EventType EVENT_TYPE = EventType.emergencyStop_DFN;
    /**
     * 加速度阀值，单位m/s2，默认-5
     */
    private int accelerationThreshold = ConfigMap.getInteger("DFN_Emergency_Stop_Acceleration_Threshold");
    /**
     * 时长阀值，单位ms，默认5000
     */
    private int durationThreshold = ConfigMap.getInteger("DFN_Emergency_Stop_Duration_Threshold");

    @Override
    public void calculate() {
        logger.debug("进入东风新版紧急停车算法.");
        VarCarStop var = super.getObj();
        CommonData commonData = super.getCommonData();

        //暂未开始紧急停车计算
        if(null == drivingData.getEventData(EVENT_TYPE)){
            //满足紧急停车的开始条件
            if(commonData.isAccStatus() && commonData.getAcceleration()<accelerationThreshold && commonData.getAcceleratorPosition()>50){
                startEventData(EVENT_TYPE);
            }
            return;
        }

        //已开始紧急停车计算
        //符合紧急停车条件
        if(commonData.isAccStatus() && commonData.getAcceleration()<accelerationThreshold){
            //油门开度为0，进行紧急停车事件合法性判断
            if(commonData.getAcceleratorPosition()==0){
                calcEventData(EVENT_TYPE);
                endEventData(EVENT_TYPE, (eventData, drivingData) ->{
                    //5秒内，速度降为0
                    if (Optional.ofNullable(eventData.getDuration()).orElse(0L) < durationThreshold) {
                        //更新统计变量
                        var.setNumber(var.getNumber()+1);

                        //放入事件输出列表
                        drivingData.addEventDataToList(eventData);
                    } else {
                        logger.debug("东风新版紧急停车算法时间{}ms,大于等于阈值{}ms，不进行统计", Optional.ofNullable(eventData.getDuration()).orElse(0L), durationThreshold);
                    }
                });
            }
            //油门开度>0，进行紧急停车数据累加
            else{
                calcEventData(EVENT_TYPE);
            }
        }else{
            //不满足紧急停车条件，删除缓存
            drivingData.removeEventData(EVENT_TYPE);
        }

        //行程结束时要清理对应的未结束事件
        if (commonData.isTripLastNode()) {
            drivingData.removeEventData(EVENT_TYPE);
        }

        logger.debug("东风新版紧急停车算法结束.");
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
        statisticDataOut.setEmergencyStopNumber_DFN(getObj().getNumber());
    }
}
